#include "utilities.h"
#include "CEventReceiver.h"
#include "CGround.h"
#include "CPrince.h"
#include "CSpider.h"
#include "CSquare.h"
#include <time.h>
#include <vector>


#define COMBO_PERIOD	5000		// Prince combo period in ms
#define SPIDER_PERIOD	2000		// Creation of a new spider period in ms

// Squares show time in ms
#define RED_SQ_DELAY	3000
#define GRN_SQ_DELAY	3000


int main()
{
	// Ask user for driver
	//E_DRIVER_TYPE driverType = driverChoiceConsole();
	
	//if (driverType == EDT_COUNT) return 1;

	CEventReceiver receiver;

	// Create device
	IrrlichtDevice* device = createDevice(/*driverType*/EDT_OPENGL,
		dimension2du(800, 600), 16, false, false, false, &receiver);
	
	if (!device) return 1;
	
	device->setWindowCaption(L"Prince - Irrlicht Engine");
	device->getCursorControl()->setVisible(false);

	// Pointers to the main objects
	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	
	// Ground
	CGround ground = CGround(device);
	vector3df groundSize = ground.getSize();

	// Prince
	CPrince prince = CPrince(device);
	prince.setPosition(groundSize/2);

	// Spiders
	array<CSpider*> spider;

	// Squares
	dimension2di squareSize = dimension2di(80, 80);

	CSquare redSquare = CSquare(driver, 
		recti(position2di (10, driver->getScreenSize().Height - squareSize.Height - 10), squareSize), 
		SColor(255, 255, 0, 0));
	
	CSquare grnSquare = CSquare(driver, 
		recti(position2di (20, driver->getScreenSize().Height - squareSize.Height - 20), squareSize), 
		SColor(255, 0, 255, 0));

	// Camera
	ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 200.f, 1.f);
	
	camera->setPosition(vector3df(groundSize.X/4, groundSize.Z/4, groundSize.Z/4));
	camera->setTarget(prince.getPosition());

	camera->setFarValue(groundSize.X*2);

	// Timers
	u32 comboTimer = device->getTimer()->getTime();
	u32 spiderTimer = device->getTimer()->getTime();
		
	int redSqTimer = -RED_SQ_DELAY;		// Minus sign required for disable the timer until it first reset
	int grnSqTimer = -GRN_SQ_DELAY;
		
	u32 refreshTimer = 0;				// Timer used for limit FPS
	u32 keyboardTimer = 0;

	srand((u32)time(NULL));


	while (device->run())
	{
		if (device->isWindowActive())
		{
			if ((device->getTimer()->getTime() - refreshTimer) > 10)	
			{
				refreshTimer = device->getTimer()->getTime();

				// If it's time to do a combo
				if ((device->getTimer()->getTime() - comboTimer) >= COMBO_PERIOD)
				{
					comboTimer = device->getTimer()->getTime();
					prince.doCombo();
				}

				u32 i = 0;
				while (i < spider.size())
				{
					// Update spider position and rotation
					spider[i]->update(prince.getPosition());

					// Check collision with prince
					if (spider[i]->checkCollision(prince.getNode()))
					{
						// Rest red square timer to show red square
						redSqTimer = device->getTimer()->getTime();
						
						// Remove spider from the scene and from the container
						delete spider[i];
						spider.erase(i);
					}
					else
					{
						++i;
					}
				}

				if ((device->getTimer()->getTime() - spiderTimer) >= SPIDER_PERIOD)
				{
					spiderTimer = device->getTimer()->getTime();

					vector3df position = vector3df();

					// Generate spider position
					do
					{
						position.X = genRandomFloat(0.f, groundSize.X);
						position.Z = genRandomFloat(0.f, groundSize.Z);
					}
					while(position.getDistanceFrom(prince.getPosition()) < groundSize.X/4);
					
					spider.push_back(new CSpider(device, position));
				}
			} // if ((device->getTimer()->getTime() - refreshTimer) > 10)

			// If any key has been pressed
			if (receiver.isAnyKeyDown() && 
				(device->getTimer()->getTime() - keyboardTimer) > 300)
			{
				keyboardTimer = device->getTimer()->getTime();

				if (!spider.empty())
				{
					// Rest green square timer to show green square
					grnSqTimer = device->getTimer()->getTime();
					
					// Remove an oldest spider from the scene and from the container
					delete spider[0];
					spider.erase(0);
				}
			}

			driver->beginScene(true, true, SColor(255, 41, 57, 85));
			
			smgr->drawAll();
			
			// Draw squares if it's needed
			if ((device->getTimer()->getTime() - redSqTimer) <= RED_SQ_DELAY)
			{
				redSquare.draw();
			}

			if ((device->getTimer()->getTime() - grnSqTimer) <= GRN_SQ_DELAY)
			{
				grnSquare.draw();
			}

			// End scene
			driver->endScene();
		} // if (device->isWindowActive())
	} // while (device->run())

	device->drop();
	return 0;
}